# -*- coding: utf-8 -*-
"""
Lib. Format
Contains various string format related functions
"""

#---------------------------------------------------------------------------
# Copyright (c) 2014 Ahmad Ghulam Zakiy <ghulam.zakiy@gmail.com>
# License: GPL3
#
# This file is part of SimpleStore
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#---------------------------------------------------------------------------

from PySide import QtGui, QtCore
import config

groupSeparator = config.application['locale'].groupSeparator()
decimalPoint = config.application['locale'].decimalPoint()
maxDigit = 9

def formatDecimal(v):
    """
     Return string formatted number with thousand separator
     based on locale used.
    """
    # TODO:
    #      1. Gunakan decimal bukan float sebisa mungkin
    #      2. Pastikan output mempunyai paling tidak 2 digit setelah titik desimalnya
    varType = type(v)
    if varType is int or varType is float or varType is long:
	v = v.__str__()

    global maxDigit, groupSeparator, decimalPoint
    newDec = ''
    numlen = 0
    precPos = -1
    precVal = ''
    decVal = ''
    decRev = ''

    v = v.replace(groupSeparator,'')
    
    if v.find(decimalPoint) != -1:
        if v.count(decimalPoint) > 1:
            print 'invalid precision number'
            return
        precPos = v.rfind(decimalPoint)
        precVal = v[precPos:]
        decVal = v[0:precPos]
    else:
        decVal = v

    decRev = decVal[::-1]

    numlen = maxDigit if len(decVal) > maxDigit else len(decVal)

    if numlen == 0:
        return ''
    if numlen <= 3:
        return decRev[::-1]+precVal
    else:
        top = max(range(0, numlen/3))
        for i in range(0, numlen/3):
            newDec = newDec + decRev[i*3:3*(1+i)] + (groupSeparator if i < top else '')
        if numlen%3 > 0:
            newDec = newDec + groupSeparator + decRev[3*(1+top):numlen]
        return newDec[::-1]+precVal


class myCustomStyle(QtGui.QStyleOptionViewItemV4):
    
    def __init__(self):
        super(myCustomStyle, self).__init__()
    


class myCustomDelegate(QtGui.QItemDelegate):
    def paint(self, painter, option, modelIndex):
        data = modelIndex.data()
        dataType = type(data)
        if dataType is float:
            data = formatDecimal(data)
            myCustomStyle = option
            myCustomStyle.displayAlignment = QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter
            self.drawDisplay(painter, myCustomStyle, myCustomStyle.rect, data)
            self.drawFocus(painter, myCustomStyle, myCustomStyle.rect)
        elif dataType is int:
            # Pastikan bahwa index table merupakan int dan bukan float
            data = unicode(data)
            myCustomStyle = option
            myCustomStyle.displayAlignment = QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter
            self.drawDisplay(painter, myCustomStyle, myCustomStyle.rect, data)
            self.drawFocus(painter, myCustomStyle, myCustomStyle.rect)
        elif dataType is long:
            data = formatDecimal(data)
            myCustomStyle = option
            myCustomStyle.displayAlignment = QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter
            self.drawDisplay(painter, myCustomStyle, myCustomStyle.rect, data)
            self.drawFocus(painter, myCustomStyle, myCustomStyle.rect)
        else:
            QtGui.QItemDelegate.paint(self, painter, option, modelIndex)
"""
    def initStyleOption(self, option, modelIndex):
        dataType = type(modelIndex.data())
        if dataType is float:
            myCustomStyle = QtGui.QStyleOptionViewItemV4()
            myCustomStyle.displayAlignment = QtCore.Qt.AlignRight
            return QtGui.QStyledItemDelegate.initStyleOption(self, myCustomStyle, modelIndex)
        if dataType is int:
            myCustomStyle = QtGui.QStyleOptionViewItemV4()
            myCustomStyle.displayAlignment = QtCore.Qt.AlignRight
            return QtGui.QStyledItemDelegate.initStyleOption(self, myCustomStyle, modelIndex)
        if dataType is long:
            myCustomStyle = QtGui.QStyleOptionViewItemV4()
            myCustomStyle.displayAlignment = QtCore.Qt.AlignRight
            return QtGui.QStyledItemDelegate.initStyleOption(self, myCustomStyle, modelIndex)
        return QtGui.QStyledItemDelegate.initStyleOption(self, option, modelIndex)

    def displayText(self, value, locale):
        if type(value) is float:
            #return locale.toString(value, 'f', 2) #still giving us +e
            return formatDecimal(value)
        return QtGui.QStyledItemDelegate.displayText(self, value, locale)
"""


def moneyfmt(value, places=2, curr='', sep=',', dp='.',
             pos='', neg='-', trailneg=''):
    """Convert Decimal to a money formatted string.

    places:  required number of places after the decimal point
    curr:    optional currency symbol before the sign (may be blank)
    sep:     optional grouping separator (comma, period, space, or blank)
    dp:      decimal point indicator (comma or period)
             only specify as blank when places is zero
    pos:     optional sign for positive numbers: '+', space or blank
    neg:     optional sign for negative numbers: '-', '(', space or blank
    trailneg:optional trailing minus indicator:  '-', ')', space or blank

    >>> d = Decimal('-1234567.8901')
    >>> moneyfmt(d, curr='$')
    '-$1,234,567.89'
    >>> moneyfmt(d, places=0, sep='.', dp='', neg='', trailneg='-')
    '1.234.568-'
    >>> moneyfmt(d, curr='$', neg='(', trailneg=')')
    '($1,234,567.89)'
    >>> moneyfmt(Decimal(123456789), sep=' ')
    '123 456 789.00'
    >>> moneyfmt(Decimal('-0.02'), neg='<', trailneg='>')
    '<0.02>'

    """
    q = Decimal(10) ** -places      # 2 places --> '0.01'
    sign, digits, exp = value.quantize(q).as_tuple()
    result = []
    digits = map(str, digits)
    build, next = result.append, digits.pop
    if sign:
        build(trailneg)
    for i in range(places):
        build(next() if digits else '0')
    build(dp)
    if not digits:
        build('0')
    i = 0
    while digits:
        build(next())
        i += 1
        if i == 3 and digits:
            i = 0
            build(sep)
    build(curr)
    build(neg if sign else pos)
    return ''.join(reversed(result))
